﻿# -*-coding:utf-8-*-
import os
import sys
# import importlib
# importlib.reload(sys)
# import codecs
# sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach())
#
reload(sys)
sys.setdefaultencoding('utf8')
import time
import datetime
import json
import socket
import shutil
import threading
# import win32file


if sys.version>'3':
    from PySide2.QtGui import *
    from PySide2.QtCore import *
    from PySide2.QtWidgets import *
else:
    from PySide2.QtGui import *
    from PySide2.QtCore import *
    from PySide2.QtWidgets import *



class WriteNodeList(QListWidget):

    nodename_Signal=Signal(str)
    def __init__(self):
        super(WriteNodeList, self).__init__()

        self.setWindowTitle(u'双击选择')
        self.doubleClicked.connect(self._choose_write)

    def _choose_write(self,index):
        item=self.itemFromIndex(index)
        text=item.text()
        self.nodename_Signal.emit(text)
        self.close()

    def init_items(self,write_list):
        if write_list:
            self.clear()
            for i in write_list:
                item=QListWidgetItem()
                item.setText(i.name())
                item.setTextAlignment(Qt.AlignCenter)
                self.addItem(item)



class Name(QWidget):

    name_Signal = Signal(str)

    def __init__(self):
        super(Name, self).__init__()
        self.main_layout = QVBoxLayout()
        self.name_label = QLabel('New Name:')
        self.name_edit = QLineEdit()
        self.name_btn = QPushButton('OK')
        self.name_btn.clicked.connect(self._set_name)
        self.main_layout.addWidget(self.name_label)
        self.main_layout.addWidget(self.name_edit)
        self.main_layout.addWidget(self.name_btn)
        self.setLayout(self.main_layout)

    def _set_name(self):
        name = self.name_edit.text()
        if name:
            self.name_Signal.emit(name)
            self.close()

class ListModel(QListWidget):

    data_Signal=Signal(dict)
    def __init__(self):
        super(ListModel, self).__init__()
        # self.clicked.connect(self._show_info)
        self.doubleClicked.connect(self._show_info)
        self.data={}
    def set_data(self,data):
        """
        :param data:
        :return:
        """
        if data:
            self.clear()
            self.data=data
            for k,v in data.items():
                item=QListWidgetItem()
                item.setText(k)
                item.setTextAlignment(Qt.AlignCenter)
                self.addItem(item)
            self.sortItems()

    def _show_info(self,index):
        item=self.itemFromIndex(index)
        text=item.text()
        self.data_Signal.emit(self.data[text])
        print('_show_info:',self.data[text])
        self.close()

    def filter_item(self,text):
        try:
            # item_list=[]
            for i in range(self.count()):
                item=self.item(i)
                project_name=item.text()
                if text not in project_name:
                    item.setHidden(True)
        except Exception as filter_item_ERR:
            print(str(filter_item_ERR))

    def add_asset(self,asset_name):
        item=QListWidgetItem()
        item.setText(asset_name)
        item.setTextAlignment(Qt.AlignCenter)
        self.addItem(item)

    def show_all(self):
        for i in range(self.count()):
            item = self.item(i)
            item.setHidden(False)

class ShotListWindow(QDialog):

    shot_Signal=Signal(dict)
    def __init__(self):
        super(ShotListWindow, self).__init__()
        self.btn_style="""QPushButton{color:black}
                                  QPushButton:hover{color:red}
                                 QPushButton{background-color:#A9A9A9}
                                  QPushButton{border:2px}
                                  QPushButton{border-radius:3px}
                                  QPushButton{padding:1px 1px}"""
        self.setWindowTitle('Shots')
        self.main_layout=QVBoxLayout()
        self.search_layout=QHBoxLayout()
        self.search_edit=QLineEdit()
        self.search_edit.textEdited.connect(self._text_edited)
        self.search_btn=QPushButton('search')
        self.search_btn.clicked.connect(self._filter_shot)
        self.search_btn.setStyleSheet(self.btn_style)
        self.add_btn=QPushButton('create')
        self.add_btn.clicked.connect(self._add_asset)
        self.add_btn.setStyleSheet(self.btn_style)
        self.search_layout.addWidget(self.search_edit)
        self.search_layout.addWidget(self.search_btn)
        self.search_layout.addWidget(self.add_btn)
        self.shot_list=ListModel()
        self.shot_list.data_Signal.connect(self._get_shot)
        self.main_layout.addLayout(self.search_layout)
        self.main_layout.addWidget(self.shot_list)
        self.setLayout(self.main_layout)

    def set_data(self,data):
        if data:
            self.shot_list.set_data(data)

    def _filter_shot(self):
        """
        filter shot
        :return:
        """
        text = self.search_edit.text()
        if text:
            self.shot_list.filter_item(text)

    def _add_asset(self):
        text = self.search_edit.text()
        if text:
            self.shot_list.add_asset(text)

    def _text_edited(self, ha):
        if not ha:  # ��û����������ʱ��������
            # self.create_items(self.data_list)
            self.shot_list.show_all()

    def _get_shot(self,data):
        self.shot_Signal.emit(data)
        self.close()

class FileListMode(QListWidget):

    path_Signal=Signal(str)
    def __init__(self):
        super(FileListMode, self).__init__()
        self.clicked.connect(self._select_path)
        self.data={}  # {'file_dir_name':path,}

    def set_data(self,data):
        if data:
            self.clear()
            self.data=data
            for k,v in data.items():
                item=QListWidgetItem()
                item.setText(k)
                self.addItem(item)
            self.sortItems()

    def _select_path(self,index):
        # print(index)
        item=self.itemFromIndex(index)
        file_name=item.text()
        path=self.data[file_name]
        self.path_Signal.emit(path)

class MZProgresBar(QWidget):

    def __init__(self):#,nk_name
        super(MZProgresBar, self).__init__()
        # self.path=nk_name
        self.main_layout=QVBoxLayout()
        self.main_layout.setSpacing(0)
        label_font=QFont('',12)
        self.show_label=QLabel(u'正在打包...')
        # self.show_label.setFont(label_font)
        # self.show_label.setStyleSheet('color: #d9d9d9')
        self.progress_layout=QHBoxLayout()
        self.progress=QProgressBar()
        self.progress.setMaximumHeight(15)
        self.percen_label=QLabel('0')
        self.percen_label.setStyleSheet('color: #d9d9d9')
        self.percen_label.setFont(label_font)
        self.progress_layout.addWidget(self.progress)
        self.progress_layout.addWidget(self.percen_label)
        self.main_layout.addWidget(self.show_label)
        self.main_layout.addLayout(self.progress_layout)
        self.setLayout(self.main_layout)

    def set_percent(self,percent):
        self.progress.setValue(percent)
        self.percen_label.setText(str(percent))


# class CopyThread(QThread):
#
#     def __init__(self,data,OUT_DIR):
#         """
#
#         :param data:
#         :param OUT_DIR: ����cgtw��RenderĿ¼�¶�Ӧ��ͷ��Ŀ¼ \\192.xxx...\Render\FNDH_0010_0020_element_v001
#         """
#         super(CopyThread, self).__init__()
#         self.data=data
#         self.OUT_DIR=OUT_DIR
#         self.all_count=0
#         self.count=0
#         self.percent=0
#
#
#
#     def mz_copy(self,origin_paths, name_list, dir_path):
#         u"""
#         �����Ǵ������֡
#         :param origin_paths: ԭ�ļ�����·���б�
#         :param name_list:  ԭ�ļ����� a.exr
#         :param dir_path: ����ļ�Ŀ¼
#         :return:
#         """
#         # per_count = len(origin_paths)
#         # percent = 0
#         # footage_path=os.path.join(dir_path,'footage')
#         if not os.path.exists(dir_path):
#             os.makedirs(dir_path)
#
#         for i in origin_paths:
#             des = os.path.join(dir_path, name_list[origin_paths.index(i)])
#             shutil.copy(i, des)
#             # win32file.CopyFile(i, des,1)
#             self.count += 1
#             self.percent = self.count * 100 / self.all_count
#
#     def show_sequence(self,dir_path, base_name):
#         u"""
#         ͨ������Ŀ¼���ļ�ͨ������,��Ҫ����Ƿ�Ϊ�ļ���������Ϊ�ļ����������ļ�ͨ����һ��������ʧ��
#         :param dir_path:
#         :param base_name: �ļ�ͨ������
#         :return:
#         """
#         sequence = []
#         file_names = []
#         file_list = os.listdir(dir_path)
#         # print('file_list:',file_list)
#         for i in file_list:
#             abs_path = os.path.join(dir_path, i)
#             if os.path.isfile(abs_path):
#                 file_names.append(i)
#                 if base_name in i:
#                     sequence.append(abs_path)
#         return sequence, file_names
#
#     def check_file(self,path):
#         u"""
#         ͨ��nuke��ȡ��·������ȡ���Ӧ·���µ�����ͬ���ļ�����
#         :param path:
#         :return:
#         """
#         file_list = []
#         name_list = []
#
#         dir_path, file_name = os.path.split(path)
#         if file_name.count('%0') > 0:
#             print(u'是序列')
#             base_name = file_name.split('%0')[0]  # �����ļ�ͨ������
#             file_list, name_list = self.show_sequence(dir_path, base_name)
#         else:
#             if os.path.isfile(path):
#                 file_list = [path]
#                 name_list = [os.path.split(path)[1]]
#                 print(u'不是序列')
#         return file_list, name_list
#
#     def run(self):
#         #project_name=self.data['project']
#         data=self.data['data']
#         self.all_count=0
#
#         for k, v in data.items():
#             file_paths, name_list = self.check_file(v[1])
#             self.all_count+=len(file_paths)
#
#         for k2,v2 in data.items():
#             dir_path = os.path.join(self.OUT_DIR,'footage',v2[0], k2)#project_name,
#             # print(dir_path)
#             file_paths, name_list = self.check_file(v2[1])
#             self.mz_copy(file_paths, name_list, dir_path)
#         # if self.all_count:
#         #     self.percent=self.count*100/self.all_count

class CopyThread(QThread):

    def __init__(self,copy_paths,parent):
        super(CopyThread, self).__init__()
        self.copy_paths = copy_paths
        self.parent = parent


    def run(self):
        for path in self.copy_paths:
            src_path,tar_path = path
            shutil.copyfile(src_path, tar_path)
            self.parent.count+=1





class ExportMov(QDialog):

    def __init__(self,parent=None):
        super(ExportMov, self).__init__(parent)
        self.HOST='192.168.1.222'
        self.PORT=4455
        self.BUFFER=20480#00
        self.cgtwpy_path = r'C:/cgteamwork_v5.3/python/python.exe'
        self.scripy_path = r'C:/cgteamwork_v5.3/bin/timeaxis_plugin/ExternalSubmit.py'  # �ύ
        self.note_path=r'C:/cgteamwork_v5.3/bin/timeaxis_plugin/ExternalNote.py'  # ��ע
        self.current_project = ''  # current selected project
        self.current_eps = ''  # current selected eps
        self.current_shot = ''  # current selected shot
        self.current_pipeline = ''  # current selected pipeline
        self.daily_dir=r'\\192.168.1.248\3d\efx\dailies'
        self.daily_path=''  #ʵʱ��������յ�daily���·��daily_path
        self.cgtw_path=''  #ʵʱ��������.......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................յ�Ҫ�ύ��cgtw�ϵ�·��
        self.write_data={}  # {'Write1':write1Node,'Write2':write2Node,...}
        self.current_nuke_path=''  #��ǰ�򿪵�nuke��ԭʼ·��������ύʱ���Ĵ�ֵ
        self.save_path=''  #��nuke�ļ����յ����·�� //192.168.1.33/FX/Render/EC12-21-34/test.nk
        self.nk_data={}    #��¼nuke����ԭʼ�����ж�Ӧ�ڵ��·����Ϣ{'project': nkname, 'data': data} eg:{'project':'FNDH','data':{'Read1':['Read','E:/AA.exr'],'vlt':['vfield_file','E:/vv/la.lvt']}} #ֻ��lut��·�����Ʋ�һ��
        self.current_write=None  #��ǰѡ�е�Write�ڵ�
        self.request_project_info={}  #request project infomation data
        self.current_project_data={}  #current selected project info #{'database': 'proj_fndh', 'entity_name': 'FNDH', 'full_name': '�����ŭ�ĺ�', 'eps_list': 'test|FNDH58|FNDH60|FNDH61|FNDH62|FNDH63|FNDH65|FNDH66|FNDH67|FNDH68|FNDH69|FNDH70|FNDH72|FNDH73|FNDH75|FNDH76|FNDH78|FNDH83|FNDH84|FNDH85|FNDH88|FNDH89|FNDH90|FNDH91|FNDH92|FNDH93|FNDH94|FNDH95|FNDH96|FNDH97|FNDH98|FNDH100|FNDH101|FNDH102|FNDH103|FNDH104|FNDH105|FNDH99|FNDH02', 'fps': '24'}
        self.current_project_config = {} #{'fps':'24','color': '#f6e7aa','resolution' :'3840x2160','path':'\\\\192.168.1.238\\cgteamwork5\\FNDH','full_name':'�����ŭ�ĺ�', 'entity_name':'FNDH'}
        self.current_shot_info = {}  # current shot info  #{'description': '���㣬�꣬���죬·����ʪ', 'entity_name': 'FNDH100_0020_01', 'img_path': '/upload/image/proj_fndh/min/51088c52f282cc9c971dd0bd767b300c.png', 'frame': '63'}
        self.task_data={}  #�þ�ͷ�������������ƶ�Ӧ��task id {'efx':{'cg_id':cg_id,'task_name':efx},'efx_��������':{'cg_id':cg_id,'task_name':efx_��������}}
        self.pipeline_nas_map={'FX':'efx','FX_Cloth':'cloth','FX_Crowd':'crowd','Environment':'sce','Env_Postviz':'env','Rig':'Rig'}
        self.pipeline_map={'FX':'efx','FX_Cloth':'efx','FX_Crowd':'efx','Environment':'env','Env_Postviz':'env','Rig':'Rig'}
        self.btn_style= """QPushButton{color:black}
                                  QPushButton:hover{color:red}
                                 QPushButton{background-color:#A9A9A9}
                                  QPushButton{border:2px}
                                  QPushButton{border-radius:3px}
                                  QPushButton{padding:1px 1px}"""

        self.setWindowTitle('ExportMov')
        self.main_layout = QVBoxLayout()
        self.main_layout.setSpacing(15)

        self.project_layout = QHBoxLayout()
        self.project_label = QLabel('Project:')
        self.choose_project_btn = QPushButton('- -')
        self.choose_project_btn.setStyleSheet(self.btn_style)
        self.choose_project_btn.clicked.connect(self._open_project_window)
        self.project_layout.addWidget(self.project_label)
        self.project_layout.addWidget(self.choose_project_btn)
        self.eps_layout = QHBoxLayout()
        self.eps_label = QLabel('Eps:')
        self.eps_comb = QComboBox()
        self.eps_comb.currentTextChanged.connect(self._eps_changed)
        self.eps_layout.addWidget(self.eps_label)
        self.eps_layout.addWidget(self.eps_comb)
        self.shot_layout = QHBoxLayout()
        self.shot_label = QLabel('Shot:')
        self.shot_list_btn=QPushButton('- -')
        self.shot_list_btn.clicked.connect(self._open_shot_window)
        self.shot_list_btn.setStyleSheet(self.btn_style)
        self.shot_layout.addWidget(self.shot_label)
        self.shot_layout.addWidget(self.shot_list_btn)
        self.pipeline_layout = QHBoxLayout()
        self.pipeline_label = QLabel('Pipeline:')
        self.pipeline_comb = QComboBox()
        self.pipeline_layout.addWidget(self.pipeline_label)
        self.pipeline_layout.addWidget(self.pipeline_comb)
        self.init_pipeline_comb()
        self.pipeline_comb.currentTextChanged.connect(self._pipeline_changed)
        self.task_name_layout=QHBoxLayout()
        self.task_name_label=QLabel('Task_name:')
        self.task_name_comb=QComboBox()
        self.task_name_comb.setMinimumWidth(250)
        self.task_name_layout.addWidget(self.task_name_label)
        self.task_name_layout.addWidget(self.task_name_comb)

        self.mov_layout=QHBoxLayout()
        self.mov_label=QLabel('mov:')
        self.mov_list_comb=QComboBox()
        self.mov_list_comb.setMinimumWidth(250)
        self.mov_layout.addWidget(self.mov_label)
        self.mov_layout.addWidget(self.mov_list_comb)
        # self.task_id_layout=QHBoxLayout()
        # self.task_id_label=QLabel('id:')
        # self.task_id_value=QLabel('-')
        self.element_layout=QHBoxLayout()
        self.element_label=QLabel('Element:')
        self.element_edit=QLineEdit()
        self.element_edit.setText('element')
        self.element_layout.addWidget(self.element_label)
        self.element_layout.addWidget(self.element_edit)
        self.fps_layout=QHBoxLayout()
        self.fps_layout.setAlignment(Qt.AlignLeft)
        self.fps_label=QLabel('FPS:')
        self.fps_edit=QLineEdit()
        self.fps_edit.setMaximumWidth(50)
        self.fps_layout.setContentsMargins(0,0,220,0)
        self.fps_layout.addWidget(self.fps_label)
        self.fps_layout.addWidget(self.fps_edit)
        self.frame_layout=QHBoxLayout()
        self.frame_label=QLabel('frame range:')
        self.start_edit=QLineEdit()
        self.end_edit=QLineEdit()
        self.patch_project_btn=QPushButton(u'使用项目设置')
        self.patch_project_btn.clicked.connect(self._patch_project_setting)
        self.patch_project_btn.setStyleSheet(self.btn_style)
        self.frame_layout.addWidget(self.frame_label)
        self.frame_layout.addWidget(self.start_edit)
        self.frame_layout.addWidget(self.end_edit)
        self.frame_layout.addWidget(self.patch_project_btn)
        self.daily_layout=QHBoxLayout()
        self.daily_label=QLabel('DailyPath:')
        self.daily_edit=QLineEdit()
        self.daily_edit.setText(self.daily_dir)
        self.daily_btn=QPushButton('...')
        self.daily_btn.setStyleSheet(self.btn_style)
        self.daily_btn.clicked.connect(self._get_daily_dir)
        self.note_layout=QHBoxLayout()
        self.note_label=QLabel('task note:')
        self.note_text=QTextEdit()
        self.note_text.setMaximumHeight(50)
        self.note_btn=QPushButton('@')
        self.note_btn.clicked.connect(self._for_note)
        self.note_layout.addWidget(self.note_label)
        self.note_layout.addWidget(self.note_text)
        self.note_layout.addWidget(self.note_btn)
        self.daily_layout.addWidget(self.daily_label)
        self.daily_layout.addWidget(self.daily_edit)
        self.daily_layout.addWidget(self.daily_btn)
        self.check_layout=QHBoxLayout()
        self.check_layout.setContentsMargins(0,20,0,10)
        self.check_layout.setSpacing(35)
        self.check_layout.setAlignment(Qt.AlignCenter)
        self.check_daily=QCheckBox(u'提交到Dailies')
        # self.check_daily.stateChanged.connect(self._check_changed)
        self.check_daily.setCheckState(Qt.Checked)
        self.check_cgtw=QCheckBox(u'提交到CGTW')
        self.check_layout.addWidget(self.check_daily)
        self.check_layout.addWidget(self.check_cgtw)
        self.btn_layout=QHBoxLayout()
        self.load_btn=QPushButton(u'载入mov')
        self.load_btn.setMinimumHeight(20)
        self.load_btn.setStyleSheet(self.btn_style)
        self.load_btn.clicked.connect(self._load_mov)
        self.version_submit_btn=QPushButton(u'设置(自增版本)')
        self.version_submit_btn.clicked.connect(self._save_update)
        self.version_submit_btn.setMinimumHeight(20)
        self.version_submit_btn.setStyleSheet(self.btn_style)
        self.cover_submin_btn=QPushButton(u'设置(覆盖版本)')
        self.cover_submin_btn.clicked.connect(self._save_cover)
        self.cover_submin_btn.setMinimumHeight(20)
        self.cover_submin_btn.setStyleSheet(self.btn_style)
        self.sumbit_btn=QPushButton(u'提交')
        self.sumbit_btn.setMinimumHeight(30)
        self.sumbit_btn.clicked.connect(self._sumbit)
        self.sumbit_btn.setStyleSheet(self.btn_style)
        self.btn_layout.addWidget(self.load_btn)
        self.btn_layout.addWidget(self.version_submit_btn)
        self.btn_layout.addWidget(self.cover_submin_btn)
        self.btn_layout.addWidget(self.sumbit_btn)

        self.text_brower = QTextBrowser()
        self.main_layout.addLayout(self.project_layout)
        self.main_layout.addLayout(self.eps_layout)
        self.main_layout.addLayout(self.pipeline_layout)
        self.main_layout.addLayout(self.shot_layout)

        self.main_layout.addLayout(self.task_name_layout)
        self.main_layout.addLayout(self.mov_layout)
        self.main_layout.addLayout(self.element_layout)
        self.main_layout.addLayout(self.fps_layout)
        self.main_layout.addLayout(self.frame_layout)
        self.main_layout.addLayout(self.daily_layout)
        self.main_layout.addLayout(self.note_layout)
        self.main_layout.addLayout(self.check_layout)
        self.main_layout.addLayout(self.btn_layout)
        self.main_layout.addWidget(self.text_brower)

        self.setLayout(self.main_layout)

        self.timer = QBasicTimer()
        self.progress = MZProgresBar()
        self.thread_list =[]
        self.count = 0
        self.all_count = 0

    def event(self, event):
        # print('AAAA')
        if event.type()==QEvent.EnterWhatsThisMode:
            QWhatsThis.leaveWhatsThisMode()
            QMessageBox.about(self,u'操作说明',u'1.选择对应的项目Project,集数Eps,阶段Pipeline,镜头Shot,任务名称Task_name\n'
                                          u'2.如果cgtw上有已提交的mov会出现在mov列表里，可以对选择的mov进行载入mov导入nukemov����nuke\n'
                                          u'3.frame range为要输出的帧范围\n'
                                          u'4.DailyPath栏为默认的dailies路径，一般不需修改'
                                          u'5.选择提交到Dailies则会直接将Write输出到Dailies里，选择提交到CGTW，会将Write\n'
                                          u'输入到cgtw对应的目录下，同时触发cgtw提交。都选择则输出2次\n'
                                          u'6.载入mov: 导入选择的mov\n'
                                          u'7.设置(自增版本)与设置(覆盖版本)都是对选中的Write节点进行配置\n')
        return QDialog.event(self,event)

    def timerEvent(self, tevent):
        # percent=self.thread.percentu
        percent= self.count * 100 / (self.all_count+0.1)
        # print(percent)
        self.progress.set_percent(percent)
        if self.all_count<5:

            if percent>90:
                print(u'pack over')
                self.progress.close()
                self._copy_save()
                self.timer.stop()

                QMessageBox.information(None, u'提示', u'文件已打包上传\n当前工程已另存')
        else:
            if percent>97:
                print(u'pack over')
                self.progress.close()
                self._copy_save()
                self.timer.stop()

                QMessageBox.information(None, u'提示', u'文件已打包上传\n当前工程已另存')


    def init_comb(self):
        """
        init drive letter
        :return:
        """
        drive_list=['ip...','A:\\','B:\\','C:\\','D:\\','E:\\','F:\\','G:\\','H:\\','I:\\','J:\\','K:\\','L:\\','M:\\','N:\\','O:\\','P:\\','Q:\\','R:\\','S:\\','T:\\',
                    'U:\\','V:\\','W:\\','X:\\','Y:\\','Z:\\']
        self.drive_comb.addItems(drive_list)
        self.drive_comb.setCurrentText('E:')

    def request_from_222(self,msg):
        """
        request data from 222
        :param msg: {'ask_type':xxx,''}
        :return:
        """
        print(msg)
        data={}
        sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        sock.settimeout(0.95)
        try:
            sock.connect((self.HOST,self.PORT))
            sock.send(str(msg).encode())
            all_backs = b''
            while True:
                #time.sleep(0.1)
                print('接收中....')
                back = sock.recv(self.BUFFER)  # socket.MSG_WAITALL#,socket.MSG_WAITALL
                # # header_len=struct.unpack(back)
                print('接受回来:', back)
                if not back:
                    break
                all_backs += back


        except Exception as request_from_222_ERR:
            print('request failed')
            print(str(request_from_222_ERR))
        finally:
            data = eval(all_backs.decode('utf8'))
            print(data)
            sock.close()

        return data


    def create_shot(self,path,shot_info):
        """
        create project
        :param path: dir path
        :param shot_info: current shot infomation
        :return:
        """
        if not os.path.exists(path):
            os.makedirs(path)
        dir_list=['hip','geo','cam','abc','tex','fbx','img','nk','hda','DCC']
        for i in dir_list:
            dirs_path=os.path.join(path,i)
            if not os.path.exists(dirs_path):
                os.makedirs(dirs_path)


    def _open_project_window(self):
        """
        request 222 get project infomation
        :return:
        """
        self.project_list_window=ListModel()
        self.project_list_window.data_Signal.connect(self._get_project_info)
        msg={'ask_type':'project'}
        data=self.request_from_222(msg)
        self.project_list_window.set_data(data)
        self.project_list_window.show()

    def _get_project_info(self,data):
        self.current_project_data=data
        project_entity_name=data['entity_name']
        # print('_get_project_info 1:',data)
        msg={'ask_type':'config','entity_name':project_entity_name}
        try:
            self.current_project_config=self.request_from_222(msg)
            # print('_get_project_info 2:',self.current_project_config)
            self.current_project_config=self.current_project_config if self.current_project_config else {'fps': '', 'color': '', 'resolution': '', 'path': '', 'full_name': '', 'entity_name': ''}
            # print('_get_project_info  self.current_project_data:',self.current_project_data)
            # print('_get_project_info  self.current_project_config:',self.current_project_config)
            self.choose_project_btn.setText(project_entity_name)
            self.fps_edit.setText(data['fps'])
            eps_list=data['eps_list'].split('|')
            self.init_eps_comb(eps_list)
        except Exception as _get_project_info_ERR:
            print(str(_get_project_info_ERR))

    def _eps_changed(self,eps):
        self.task_name_comb.clear()
        self.mov_list_comb.clear()

        self.shot_list_btn.setText('- -')

    def _pipeline_changed(self,pipeline):
        if pipeline=='Environment':
            self.daily_dir = r'\\192.168.1.248\3d\env\dailies'
            self.daily_edit.setText(self.daily_dir)
        self.task_name_comb.clear()
        self.mov_list_comb.clear()
        cgtw_path = self.current_project_config['path']
        shot_name=self.shot_list_btn.text()
        eps=self.eps_comb.currentText()
        # pipeline=self.pipeline_comb.currentText()
        self.init_mov_comb(cgtw_path,eps,shot_name,pipeline)


    def _patch_project_setting(self):
        import nuke
        root=nuke.Root()
        start=root['first_frame'].value()
        end=root['last_frame'].value()
        self.start_edit.setText(str(int(start)))
        self.end_edit.setText(str(int(end)))

    def _get_daily_dir(self):
        """
        get daily director path
        :return:
        """
        dir = QFileDialog.getExistingDirectory(self, u'选择目录')  # ,dir=hou.getenv('JOB')


    def _open_shot_window(self):
        """
        request 222, get shot info
        :return:
        """

        # print('_open_shot_window:',self.current_project_data)
        # print('current_project_config:',self.current_project_config)
        if self.current_project_data:
            database = self.current_project_data['database']
            eps=self.eps_comb.currentText()

            self.shot_info_window=ShotListWindow()
            self.shot_info_window.shot_Signal.connect(self._get_shot_info)
            msg = {'ask_type': 'shot','database':database,'eps':eps}
            data = {}
                # msg = {'ask_type': 'asset', 'database': database, 'eps': eps}
            if eps != 'Asset':
                data=self.request_from_222(msg)
                # print('_open_shot_window,data:',data)
            else:
                project = self.choose_project_btn.text()
                if project != '- -':
                    project_path=self.current_project_config['path']
                    pipeline=self.pipeline_comb.currentText()
                    asset_path = os.path.join(project_path, 'Asset_work',pipeline)
                    print('asset_path:',asset_path)
                    if os.path.exists(asset_path):
                        asset_dirs=os.listdir(asset_path)
                        for d in asset_dirs:
                            if not d.startswith('.'):
                                data[d]={'description': '', 'entity_name': d, 'img_path': 'path', 'frame': '100'}
            self.shot_info_window.set_data(data)
            self.shot_info_window.show()


    def set_task_name(self,data):
        """
        set the task_name_comb items
        :param data:
        :return:
        """
        self.task_name_comb.clear()
        if data:
            # print('set_task_name:',data)
            self.task_data=data
            self.task_name_comb.addItems(list(data.keys()))

    def _get_shot_info(self,data):
        """
        slot back shot data
        :param data:{'description': '���㣬�꣬���죬������ͷ���ˣ������������ˣ���', 'entity_name': 'FNDH100_0100',
        'img_path': '/upload/image/proj_fndh/min/591ec4e0a401d83bb1f1738c6846d35d.png', 'frame': '107'}
        :return:
        """
        # print('_get_shot_info data:',data)
        self.current_shot_info=data
        shot_name=data['entity_name']
        self.shot_list_btn.setText(shot_name)
        self.set_frame_range(data['frame'])
        eps=self.eps_comb.currentText()
        pipeline_show=self.pipeline_comb.currentText()
        pipeline=self.pipeline_map[pipeline_show]

        cgtw_path = self.current_project_config['path']
        eps = self.eps_comb.currentText()
        # pipeline_text = self.pipeline_comb.currentText()
        if eps!='Asset':
            msg = {'ask_type': 'task', 'database': self.current_project_data['database'], 'eps': eps,'shot_name':shot_name,'pipeline':pipeline}
            # print('msg:',msg)
            task_data = self.request_from_222(msg)  #����þ�ͷ�����е�task_name��cgtw��task��id
            self.set_task_name(task_data)
            # print('_get_shot_info:',data)
            # print('task_data:',task_data)
            self._show_shot_info()#self.current_shot_info

            self.init_mov_comb(cgtw_path,eps,shot_name,pipeline_show)
        else:
            asset_path=os.path.join(cgtw_path,'Asset_work',pipeline_show,shot_name)
            self.init_asset_mov_comb(asset_path)
            # pass

    def set_frame_range(self,frame):
        self.start_edit.setText('1')
        self.end_edit.setText(frame)


    def get_relative_data(self,cgtw_path,eps,shot_name,pipeline):
        data={}
        if pipeline=='mm':
            path = os.path.join(cgtw_path, 'Shot_work', 'Matchmove', eps)
            data = {}
            if os.path.exists(path):
                file_list = os.listdir(path)
                print('path:',path)
                for i in file_list:
                    name=i.split('_mm')[0]
                    if shot_name == name and i.endswith('.fbx') and not i.startswith('.'):
                        data[i] = os.path.join(path, i)
            # data[pipeline] = data
        if pipeline=='ani':
            path = os.path.join(cgtw_path, 'Shot_work', 'Animation', eps,shot_name,'maya_file')
            data = {}
            if os.path.exists(path):
                file_list = os.listdir(path)
                for i in file_list:
                    name = i.split('_ani')[0]
                    if shot_name == name or i.endswith('.ma') or i.endswith('.abc') and not i.startswith('.'):
                        data[i] = os.path.join(path, i)
            # data[pipeline] = data
        if pipeline=='env':
            path = os.path.join(cgtw_path, 'Shot_work', 'Environment', eps,'Render')
            data = {}
            if os.path.exists(path):
                file_list = os.listdir(path)
                for i in file_list:
                    name = i.split('_env')[0]
                    if shot_name == name and not i.startswith('.'):
                        data[i] = os.path.join(path, i)
            # data[pipeline] = data
        return data

    def get_mov_list(self,cgtw_path, eps, shot_name, pipeline):
        path = os.path.join(cgtw_path, 'Shot_work', pipeline, eps)
        print('get_mov_list: path:',path)
        print('get_mov_list: pipeline:', pipeline)
        # data = {}
        mov_list=[]
        if os.path.exists(path):
            file_list = os.listdir(path)
            for i in file_list:
                name = i.split('_efx')[0] if pipeline=='FX' else i.split('_env')[0]
                if shot_name == name and not i.startswith('.'):
                    # data[i] = os.path.join(path, i)
                    # mov_list.append(os.path.join(path, i))
                    mov_list.append(i)
        return mov_list


    def init_config(self, config_path):
        config_data = {}
        if os.path.exists(config_path):
            with open(config_path, 'r') as r:  # ,encoding='utf8'
                config_data = eval(r.read())
        # print('config_data:', config_data)
        return config_data

    def init_data(self, path):
        data = {}
        if os.path.exists(path):
            with open(path, 'r', encoding='utf8') as r:  # ,encoding='utf8'
                data = eval(r.read())
        # print('data:', data)
        return data

    def init_project_comb(self, data):
        """
        init project_comb items
        :param data:
        :return:
        """
        if data:
            self.project_comb.clear()
            self.project_comb.addItems(sorted(list(data.keys())))

    def init_eps_comb(self,eps_list):
        """
        init eps items
        :return:
        """
        self.eps_comb.clear()
        s_list=sorted(eps_list)
        s_list.insert(0,'Asset')
        self.eps_comb.addItems(s_list)
        self.current_eps = self.eps_comb.currentText()

    def init_shot_comb(self):
        """
        init shot comb items
        :return:
        """
        current_project = self.project_comb.currentText()
        current_eps = self.eps_comb.currentText()
        if current_project and current_eps:
            shot_dir = os.path.join(self.project_root_path, current_project, current_eps)
            if os.path.exists(shot_dir):
                shot_list = os.listdir(shot_dir)
                self.shot_comb.clear()
                self.shot_comb.addItems(sorted(shot_list))

    def init_pipeline_comb(self):
        pipeline_list=['FX','FX_Cloth','FX_Crowd','FX_Hair','Environment','Env_Postviz','Rig']
        self.pipeline_comb.addItems(pipeline_list)

    def init_mov_comb(self,cgtw_path,eps,shot_name,pipeline):
        print('init_mov_comb:',cgtw_path,eps,shot_name,pipeline)
        self.mov_list_comb.clear()

        mov_list = self.get_mov_list(cgtw_path, eps, shot_name, pipeline)
        self.mov_list_comb.addItems(mov_list)

    def init_asset_mov_comb(self,asset_path):
        self.mov_list_comb.clear()
        movs=os.listdir(asset_path)
        if movs:
            self.mov_list_comb.addItems(movs)

    def _show_shot_info(self):#, shot_info
        """
        pipeline changed  update the shot info
        :return:
        """
        # show_text = ''
        if self.current_shot_info:
            # print(shot_info)
            show_text ='项目: {}'.format(self.current_project_data['full_name'])+'\n'+'FPS: {}'.format(self.current_project_data['fps'])+'\n' \
                        +'分辨率: {}'.format(self.current_project_config['resolution'] if self.current_project_config['resolution'] else '')+'\n'+'项目路径: {}'.format(self.current_project_config['path'] if self.current_project_config['path'] else '')+'\n'\
                       +'帧数: {}'.format(self.current_shot_info['frame'] if self.current_shot_info['frame'] else '' +'\n' + '制作内容: {}'.format(self.current_shot_info['description'] if self.current_shot_info['description'] else ''))
            self.text_brower.setText(show_text)

    def _load_mov(self):
        """
        open existed hip
        :return:
        """
        # drive=self.drive_btn.text()
        path=self.current_project_config['path']
        # project=self.choose_project_btn.text()
        eps=self.eps_comb.currentText()
        mov_name=self.mov_list_comb.currentText()
        pipeline=self.pipeline_comb.currentText()
        hip_name=self.mov_list_comb.currentText()
        if mov_name!='- -' and eps and hip_name:
            mov_path = os.path.join(path,'Shot_work',pipeline,eps, mov_name)
            import nuke
            read=nuke.nodes.Read()
            read['file'].fromUserText(mov_path)
            read.setSelected(True)
            read.showControlPanel()

    def save_new_file(self, new_name):
        """
        slot from name window ,save new file
        :param new_name:
        :return:
        """
        drive=self.drive_btn.text()
        project=self.choose_project_btn.text()
        eps=self.eps_comb.currentText()
        shot=self.shot_list_btn.text()
        pipeline=self.pipeline_comb.currentText()
        if project!='- -' and shot!='- -' and eps:
            dir_path=os.path.join(drive,project,eps,shot,pipeline)
            hip_name=shot+'_'+pipeline+'_'+new_name+'_v001.hip'#project+'_'+eps+'_'+
            hip_path=os.path.join(dir_path,'hip',hip_name)
            print(dir_path)
            print(hip_path)
            self.create_shot(dir_path,self.current_shot_info)


    def _save_file(self):
        """
        save current hip to the path as its shot name
        :return:
        """
        new_file = ''
        # current_shot_name=self.current_shot.currentText()
        self.name_window = Name()
        self.name_window.name_Signal.connect(self.save_new_file)
        self.name_window.show()


    def int2str(self,number):
        if number < 10:
            return 'v00' + str(number)
        elif number < 100:
            return 'v0' + str(number)
        else:
            return 'v' + str(number)

    def update_version(self,ori_version):
        new_file_name = ''
        file_name, ex_name = os.path.splitext(ori_version) #a_b_v001.mov
        slite_files = file_name.split('_')#[a,b,v001]
        vers = slite_files[-1]
        slite_files.remove(vers)
        if vers.startswith('v'):
            num = vers[1:]
            new_ver = int(num) + 1
            version = self.int2str(new_ver)
            slite_files.append(version)
            new_file_name = '_'.join(slite_files) + ex_name
        else:
            new_file_name = file_name + '_v001' + ex_name
        return new_file_name

    def _save_update(self):
        """
        autosave file update version
        """
        pipeline=self.pipeline_comb.currentText()
        pipeline_name=self.pipeline_map[pipeline]#self.pipeline_nas_map[pipeline]
        eps=self.eps_comb.currentText()
        element=self.element_edit.text()
        cgtw_path=self.current_project_config['path']
        pre_daily_dir_path=self.daily_edit.text()
        current_mov=self.mov_list_comb.currentText()
        new_file=''
        if current_mov:
            new_file=self.update_version(current_mov)
            print('new_mov_name:',new_file)
        else:
            shot_name=self.shot_list_btn.text()
            new_file=shot_name+'_'+pipeline_name+'_{}_v001.mov'.format(element)
            if pipeline_name=='env':
                new_file = shot_name + '_' + pipeline_name + '_v001.mov'
            if self.mov_list_comb.findText(new_file) < 0:
                self.mov_list_comb.addItems([new_file])
            self.mov_list_comb.setCurrentText(new_file)
            print('No:',new_file)
        cgtw_mov_path=os.path.join(cgtw_path, 'Shot_work', pipeline,eps,new_file)
        self.cgtw_path=cgtw_mov_path
        print('cgtw_mov_path:',cgtw_mov_path)

        #get daily path
        daily_dir_path=self.get_daily_dir_path()

        check_status=self.check_path_status()
        if check_status==1:  #���ύdaily
            self.daily_path = os.path.join(daily_dir_path, new_file)
            print('daily_path:', self.daily_path)
            self.write_daily(self.daily_path)
        if check_status==2: #���ύ��
            self.write_daily(self.cgtw_path)
        if check_status==3: #���ύcgtw
            self.write_daily(self.cgtw_path)


    def get_daily_dir_path(self):
        """
        ��ȡdaily mov�����Ŀ¼�����������Լ����������
        :return:
        """
        daily_dir_path = ''
        pre_daily_dir_path = self.daily_edit.text()
        current_mov = self.mov_list_comb.currentText()
        pipeline = self.pipeline_comb.currentText()
        date,apm=self.get_date(pipeline)
        if apm:
            daily_dir_path=os.path.join(pre_daily_dir_path,date,apm)
        else:
            daily_dir_path=os.path.join(pre_daily_dir_path,date)
        return daily_dir_path


    def get_daily_mov_path(self):
        """
        ����write�ڵ��ϵ�mov������daily��dirĿ¼�������ص�ǰdaily_mov�����·����ǰ�������������Write�ڵ㣬
        Write�ڵ���������daily����cgtw���·��
        :return:
        """
        daily_mov_path = ''
        if self.current_write:
            file_path = self.current_write['file'].value()
            mov = os.path.split(file_path)[1]
            daily_dir_path = self.get_daily_dir_path()
            daily_mov_path = os.path.join(daily_dir_path, mov)
        return daily_mov_path,daily_dir_path

    def _save_cover(self):
        pipeline = self.pipeline_comb.currentText()
        pipeline_name =self.pipeline_map[pipeline] #self.pipeline_nas_map[pipeline]
        task_name = self.task_name_comb.currentText()
        eps = self.eps_comb.currentText()
        cgtw_path = self.current_project_config['path']
        pre_daily_dir_path = self.daily_edit.text()
        current_mov = self.mov_list_comb.currentText()
        shot_name=self.shot_list_btn.text()
        element = self.element_edit.text()
        # new_file = shot_name + '_' + pipeline_name + '_{}_v001.mov'.format(element)
        # new_file = shot_name + '_' + task_name + '_{}_v001.mov'.format(element)
        new_file = shot_name + '_efx_{}_v001.mov'.format(element)  # eg:HYX-05-03-efx_element_v001.mov
        if pipeline_name=='env':
            # new_file = shot_name + '_' + pipeline_name + '_v001.mov'
            new_file = shot_name + '_' + task_name + '_v001.mov'
        if self.mov_list_comb.findText(new_file) < 0:
            self.mov_list_comb.addItems([new_file])
        self.mov_list_comb.setCurrentText(new_file)
        print('No:', new_file)
        if eps!='Asset':
            cgtw_mov_path = os.path.join(cgtw_path, 'Shot_work', pipeline, eps, new_file)
        else:
            cgtw_mov_path = os.path.join(cgtw_path, 'Asset_work', pipeline,shot_name,new_file)
        self.cgtw_path = cgtw_mov_path
        print('cgtw_mov_path:', cgtw_mov_path)

        daily_dir_path = ''
        date, apm = self.get_date(pipeline)
        if apm:
            daily_dir_path = os.path.join(pre_daily_dir_path, date, apm)
        else:
            daily_dir_path = os.path.join(pre_daily_dir_path, date)

        if self.check_daily.isChecked():
            if not self.check_cgtw.isChecked():  # ���ύ��daily
                self.daily_path = os.path.join(daily_dir_path, new_file)
                print('daily_path:', self.daily_path)
                self.write_daily(self.daily_path)

            else:  # cgtwҲ��ѡ���ˣ���ôwrite��Ӧ����cgtw��·��
                self.write_daily(self.cgtw_path)
        else:
            if self.check_cgtw.isChecked():
                self.write_daily(self.cgtw_path)

    def check_path_status(self):
        status=0  #û��ѡ
        if self.check_daily.isChecked():
            if not self.check_cgtw.isChecked():
                status=1  #���ύdaily
            else:
                status=2  #���ύ
        else:
            if self.check_cgtw.isChecked():
                status=3  #��cgtw�ύ

        return status

    def cmd_cgtw_submit(self,database,shot,task_id):#,movpath
        """
        �ύ��cgtw
        :param database:
        :param shot:
        :param task_id:
        :param movpath:
        :return:
        """
        cmd = '''"{}" "{}" "{}" "{}" "{}"'''.format(self.cgtwpy_path,self.scripy_path,database,shot,task_id)#,movpath
        print('cmd:',cmd)
        import subprocess
        subprocess.Popen(cmd,shell=True)
        print('submit over')

    def cmd_cgtw_note(self,database,task_id,note):#,movpath
        """
        �ύ��cgtw
        :param database:
        :param shot:
        :param task_id:
        :param movpath:
        :return:
        """
        # print('cmd_cgtw_note01')
        print('ori_note',note)
        print('note:',note.replace('\\','\\\\'))
        # cmd = u'''"{}" "{}" {} "{}" "{}"'''.format(self.cgtwpy_path,self.note_path,database,task_id,note)#,movpath
        cmd = [self.cgtwpy_path,self.note_path,database,task_id,json.dumps(note)]
        # print('cmd_cgtw_note02')
        # cmd=cmd.encode(locale.getdefaultlocale()[1])
        print('cmd:',cmd)
        import subprocess
        subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
        print('note over')

    def read_info(self,dir_path,nuke_name):
        """
        ��ȡȫ�ִ����Ϣ
        :param dir_path: nuke������ļ�Ŀ¼ \\...shot_name_v00x
        :param nuke_name: test.nk ���ļ�����β׺
        :return: {'Read1':['Read',path],'Read2:'['Read',path],'Camera1':['Camera2',path]} �����ǽڵ����ƶ�Ӧ���б���Ϣ��
        �б��һ�������ͣ��ڶ�����·��
        """
        import nuke
        nkname=os.path.splitext(nuke_name)[0]
        save_path = os.path.join(dir_path, nuke_name)  # E:/AA/test/test.nk
        self.save_path=save_path
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)
        data = {}
        sn = nuke.allNodes()
        for n in sn:
            # n.Class()
            name = n.name()
            if n.Class() in ['Camera2', 'ReadGeo2', 'Read','DeepRead']:  #, 'Write'
                file = n['file'].value()
                file_name = os.path.split(file)[1]
                data[name] = [n.Class(), file]
                new_path = os.path.join('footage', n.Class(), name, file_name)  # footage/Read/read1/aa.text
                n['file'].setValue(new_path.replace('\\', '/'))
            elif n.Class() == 'Vectorfield':
                file = n['vfield_file'].value()
                file_name = os.path.split(file)[1]
                data[name] = [n.Class(), file]
                new_path = os.path.join('footage', n.Class(), name, file_name)
                n['vfield_file'].setValue(new_path.replace('\\', '/'))
        rt = nuke.Root()
        rt['project_directory'].setValue(dir_path.replace('\\', '/'))
        # nuke.scriptSave(save_path)
        project_data = {'project': nkname, 'data': data}
        self.nk_data=project_data
        # print('data:', project_data)
        return project_data

    def show_sequence(self,dir_path, base_name):
        u"""
        ͨ������Ŀ¼���ļ�ͨ������,��Ҫ����Ƿ�Ϊ�ļ���������Ϊ�ļ����������ļ�ͨ����һ��������ʧ��
        :param dir_path:
        :param base_name: �ļ�ͨ������
        :return:
        """
        sequence = []
        file_names = []
        file_list = os.listdir(dir_path)
        # print('file_list:',file_list)
        for i in file_list:
            abs_path = os.path.join(dir_path, i)
            if os.path.isfile(abs_path):
                file_names.append(i)
                if base_name in i:
                    sequence.append(abs_path)
        return sequence, file_names

    def check_file(self,path):
        u"""
        ͨ��nuke��ȡ��·������ȡ���Ӧ·���µ�����ͬ���ļ�����
        :param path:
        :return:
        """
        file_list = []
        name_list = []

        dir_path, file_name = os.path.split(path)
        if file_name.count('%0') > 0:
            print(u'是序列')
            base_name = file_name.split('%0')[0]  # �����ļ�ͨ������
            file_list, name_list = self.show_sequence(dir_path, base_name)
        else:
            if os.path.isfile(path):
                file_list = [path]
                name_list = [os.path.split(path)[1]]
                print(u'不是序列')
        return file_list, name_list

    # def mz_copy(self,origin_paths, name_list, dir_path):
    #     u"""
    #     �����Ǵ������֡
    #     :param origin_paths: ԭ�ļ�����·���б�
    #     :param name_list:  ԭ�ļ����� a.exr
    #     :param dir_path: ����ļ�Ŀ¼
    #     :return:
    #     """
    #
    #     if not os.path.exists(dir_path):
    #         os.makedirs(dir_path)
    #     for i in origin_paths:
    #         des = os.path.join(dir_path, name_list[origin_paths.index(i)])
    #         shutil.copy(i, des)
    #         self.count += 1
    #         self.percent = self.count * 100 / self.all_count

    def get_copy_paths(self,origin_paths, name_list, dir_path):
        copy_paths = []
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)
        for i in origin_paths:
            des = os.path.join(dir_path, name_list[origin_paths.index(i)])
            copy_paths.append((i,des))
        return copy_paths

    def clip_list(self,a, c):  #
        clip_back = []
        if len(a) > c:
            for i in range(int(len(a) / c)):
                # print(i)
                clip_a = a[c * i:c * (i + 1)]
                clip_back.append(clip_a)


            last = a[int(len(a) / c) * c:]
            if last:
                clip_back.append(last)
        else:
            clip_back = [a]

        return clip_back

    def pack(self,cgtw_dir_path,nkfile):
        """
        ������ļ�
        :param cgtw_dir_path: �����Ŀ¼  \\\\192.168.1.239\\cgteamwork4\\PLTEST\\Shot_work\\FX\\eps01\\Render\\tam05_01_003_efx_element_v001
        :param nkfile:  test.nk ���ļ�β׺������
        :return:
        """
        print('pack start')
        self.count = 0
        self.all_count = 0
        if self.thread_list:
            for t in self.thread_list:
                t.quit()
                t.wait()
        print('pack 001')
        infp_data=self.read_info(cgtw_dir_path,nkfile)

        data = infp_data['data']

        for k, v in data.items():
            file_paths, name_list = self.check_file(v[1])
            self.all_count+=len(file_paths)
        print('all_count:',self.all_count)
        all_path_list = []
        for k2,v2 in data.items():
            dir_path = os.path.join(cgtw_dir_path,'footage',v2[0], k2)#project_name,
            # print(dir_path)
            file_paths, name_list = self.check_file(v2[1])
            copy_paths =self.get_copy_paths(file_paths, name_list, dir_path)
            all_path_list.extend(copy_paths)

        # print('len:all_path_list:',len(all_path_list),all_path_list[0])

        self.progress.show()
        self.timer.start(150, self)
        # self.thread = CopyThread(cliped_list, self)

        # self.thread.start()
        print('progress show')
        cliped_list = self.clip_list(all_path_list,5)
        # print('cliped_list:',cliped_list)

        thread_list = []
        for i in cliped_list:
            th = CopyThread(i, self)
            thread_list.append(th)
            th.start()
        self.thread_list = thread_list

    def _copy_save(self):
        """
        �ȱ��汾��nuke���̣���ʱ�ļ�·�������޸Ĺ������·��
        Ȼ�󽫱����������Ƶ�����ύ�ĵط�
        ��󽫱����̵��������·���ָ�����յ�Project Settings�е�project directory
        :return:
        """
        import nuke
        nuke.scriptSave("")
        shutil.copyfile(self.current_nuke_path,self.save_path)
        # win32file.CopyFile(self.current_nuke_path,self.save_path,1)
        self.reset_paths()
        nuke.scriptSave('')

    def reset_paths(self):
        """
        ����ԭ��¼�Ľڵ�ԭʼ·����Ϣ
        :return:
        """
        import nuke
        #self.nk_data ={'project':'FNDH','data':{'Read1':['Read','E:/AA.exr'],'vlt':['vfield_file','E:/vv/la.lvt']}}
        if self.nk_data:
            data=self.nk_data['data']
            for k,v in data.items():
                node=nuke.toNode(k)
                nodetype=v[0]
                filepath=v[1]
                file_path_name='file' if nodetype!='Vectorfield' else 'vfield_file'
                node[file_path_name].setValue(filepath)
            root=nuke.Root()
            root['project_directory'].setValue('')
        print('reset_paths done')

    def _for_note(self):
        note = self.note_text.toPlainText().replace(' ','_')
        eps = self.eps_comb.currentText()
        database = self.current_project_data['database']
        task_name = self.task_name_comb.currentText().encode('utf-8') if eps != 'Asset' else ''
        cg_id = self.task_data[task_name]['cg_id'] if eps != 'Asset' else ''
        task_id = cg_id.split(',')[2] if eps != 'Asset' else ''
        if note:
            if eps != 'Asset':
                self.cmd_cgtw_note(database, task_id, note)

    def _sumbit(self):
        import nuke
        root = nuke.Root()
        nkpath = root['name'].value()
        self.current_nuke_path=nkpath
        if not nkpath:
            QMessageBox.information(self,u'提示,',u'请先保存当前nuke工程')
        else:
            nuke.scriptSave("")  # �ȱ��ر���һ��
            nkfile = os.path.split(nkpath)[1] #a.nk'
            nkname = os.path.splitext(nkfile)[0]


            database=self.current_project_data['database']
            eps=self.eps_comb.currentText()
            shot=self.shot_list_btn.text()
            fps=self.fps_edit.text()
            start=self.start_edit.text()
            start=start if start else '0'
            end=self.end_edit.text()
            end=end if end else '0'
            task_name=self.task_name_comb.currentText().encode('utf-8') if eps!='Asset' else ''
            cg_id=self.task_data[task_name]['cg_id'] if eps!='Asset' else ''
            task_id=cg_id.split(',')[2] if eps!='Asset' else ''
            print('task_id:',task_id)
            check_status=self.check_path_status()
            print('check_status:',check_status)
            # print()
            self.daily_path,daily_dir_path=self.get_daily_mov_path()
            cgtw_dir = os.path.split(self.cgtw_path)[0]
            note = self.note_text.toPlainText().replace(' ','_').replace(',','_')

            file_path = self.current_write['file'].value() #ͨ����ǰWrite�����·����ȡ��ȷ���������
            mov = os.path.split(file_path)[1]
            mov_name=os.path.splitext(mov)[0]  #ȥ��β׺,�õ���ȷ���ύĿ¼����
            cgtw_render_dir=os.path.join(cgtw_dir,'Render',mov_name)  #��Ⱦ�ļ������Ŀ¼
            print('cgtw_render_dir:',cgtw_render_dir)
            astype='shot' if eps!='Asset'else 'asset'
            if check_status==1:  #���ύdaily
                print(u'仅提交daily')
                if not os.path.exists(daily_dir_path):
                    os.makedirs(daily_dir_path)
                nuke.execute(self.current_write.name(),int(float(start)),int(float(end)),1)
            elif check_status==2:
                print(u'两者都写')
                print(self.daily_path,self.cgtw_path)

                if not os.path.exists(daily_dir_path):
                    os.makedirs(daily_dir_path)
                if not os.path.exists(cgtw_dir):
                    os.makedirs(cgtw_dir)
                # д��daily
                self.setWriteConfig(self.current_write,self.daily_path,int(fps), int(float(start)), int(float(end)))
                nuke.execute(self.current_write.name(),int(float(start)), int(float(end)), 1)
                # д��cgtw
                self.setWriteConfig(self.current_write, self.cgtw_path, int(fps),
                                    int(float(start)), int(float(end)))
                result=QMessageBox.question(self,u'提示',u'是否打包nuke文件到cgtw？',QMessageBox.Yes|QMessageBox.No,QMessageBox.No)
                if result==QMessageBox.Yes:
                    nuke.execute(self.current_write.name(), int(float(start)), int(float(end)), 1)  # д��cgtw
                    self.pack(cgtw_render_dir, nkfile) #���
                    if eps != 'Asset':
                        self.cmd_cgtw_submit(database,shot,task_id)#,shot
                    if note:
                        if eps != 'Asset':
                            self.cmd_cgtw_note(database,task_id,note)
                else:
                    nuke.execute(self.current_write.name(), int(float(start)), int(float(end)), 1)  # д��cgtw
                    if note:
                        if eps != 'Asset':
                            self.cmd_cgtw_note(database,task_id,note)
            elif check_status==3:
                print(u'仅cgtw提交')
                if not os.path.exists(cgtw_dir):
                    os.makedirs(cgtw_dir)
                self.setWriteConfig(self.current_write, self.cgtw_path, int(fps),
                                    int(float(start)), int(float(end)))
                # print('��cgtw�ύ02')
                #nuke.execute(self.current_write.name(), int(float(start)), int(float(end)), 1) #д��cgtw
                result=QMessageBox.question(self,u'提示',u'是否打包nuke文件到cgtw？',QMessageBox.Yes|QMessageBox.No,QMessageBox.No)
                # print('��cgtw�ύ03')
                # print(result)
                if result==QMessageBox.Yes:
                    nuke.execute(self.current_write.name(), int(float(start)), int(float(end)), 1)  # д��cgtw
                    self.pack(cgtw_render_dir, nkfile) #���
                    if eps != 'Asset':
                        self.cmd_cgtw_submit(database,shot,task_id)#,shot
                        if note:
                            # print('��cgtw�ύ04')
                            self.cmd_cgtw_note(database, task_id, note)
                else:
                    nuke.execute(self.current_write.name(), int(float(start)), int(float(end)), 1)  # д��cgtw
                    print(u'不打包')
                    if note:
                        if eps != 'Asset':
                            print('cmd_cgtw_submit:',database,shot,task_id)
                            self.cmd_cgtw_note(database, task_id, note)  #.decode('gbk')


    def setWriteConfig(self,write, path, fps,start,end):
        write['file'].fromUserText(path)
        # write['meta_codec'].setValue('avc1')
        write['mov64_fps'].setValue(fps)
        write['first'].setValue(start)
        write['last'].setValue(end)



    def write_daily(self,path):
        import nuke
        self.write_data.clear()
        fps=self.fps_edit.text()
        start=self.start_edit.text()
        start=start if start else '0'
        end=self.end_edit.text()
        end=end if end else '0'
        sn = nuke.selectedNodes()
        writes = []
        for i in sn:
            if i.Class() == 'Write':
                writes.append(i)
                write_name = i.name()
                self.write_data[write_name] = i
                print('has')
        if writes:  #ѡ��Ľڵ��в�ѯ
            if len(writes) == 1:
                w = writes[0]
                w.setSelected(True)
                w.showControlPanel()
                self.current_write=w
                w['meta_codec'].setValue('avc1')  #set H264
                self.setWriteConfig(w, path, int(fps),int(float(start)),int(float(end)))
            else:
                self.writes_list_window=WriteNodeList()
                self.writes_list_window.nodename_Signal.connect(self._set_write)
                self.writes_list_window.init_items(writes)
                self.writes_list_window.show()

        else:  #ѡ�еĽڵ���û��write����ô��ȫ�ֽڵ��в�ѯ
            print('find all nodes')
            allnode = nuke.allNodes()
            allWrites=[]
            for n in allnode:
                if n.Class() == 'Write':
                    allWrites.append(n)
                    write_name = n.name()
                    self.write_data[write_name] = n
            if allWrites:
                self.writes_list_window = WriteNodeList()
                self.writes_list_window.nodename_Signal.connect(self._set_write)
                self.writes_list_window.init_items(allWrites)
                self.writes_list_window.show()

    def _set_write(self,write_name):
        fps=self.fps_edit.text()
        start=self.start_edit.text()
        start=start if start else '0'
        end=self.end_edit.text()
        end=end if end else '0'
        w=self.write_data[write_name]
        w.setSelected(True)
        w.showControlPanel()
        self.current_write=w
        check_status=self.check_path_status()
        set_path=''
        if check_status>1:  #����ѡ����cgtw
            set_path=self.cgtw_path
        else:
            set_path=self.get_daily_mov_path()[0]
        w['meta_codec'].setValue('avc1')  #set H264
        self.setWriteConfig(w, set_path, int(fps),int(float(start)),int(float(end)))


    def getWeekNum(self,date):
        """
        �������ڷ��أ�������������һ�ܵ����λ��
        :param date: 2020-08-13 ���ָ�ʽ
        :return:
        """
        str_year, str_month, str_day = date.split('-')
        weeknum = datetime.datetime(int(str_year), int(str_month), int(str_day)).strftime('%w')
        return int(weeknum)

    def delta_date(self,start_date, end_date):
        """
        ������ʼ��������ڳ���
        :param start_date:
        :param end_date:
        :return:
        """
        start = datetime.datetime.strptime(start_date, "%Y-%m-%d")
        end = datetime.datetime.strptime(end_date, "%Y-%m-%d")
        delta_day = (end - start).days
        return delta_day

    def dateAdd(self,start_date, days):
        """
        ����ȷ�����ڼӷ�
        :param start_date:
        :param days:
        :return:
        """
        d = datetime.datetime.strptime(start_date, '%Y-%m-%d')
        delta = datetime.timedelta(days=days)
        n_days = d + delta
        return (n_days.strftime('%Y-%m-%d'))

    def getWeekdayNum(self, int_year, int_month, int_day):
        '''
        ��ȡ���ڼ�
        :return:
        '''
        # ���ǻ�ȡ��ǰ����

        weekday = datetime.datetime(int_year, int_month, int_day).strftime("%w")
        # print(weekday)
        return int(weekday)


    def getNearWeekNum(self,num):
        near_num = 0
        if num <= 2:
            near_num = 2
        elif num <= 4:
            near_num = 4
        elif num <= 6:
            near_num = 6
        return near_num


    def get_date(self,pipeline):
        """
        for dailies date direction
        :param pipeline:
        :return:
        """
        today = time.strftime("%Y-%m-%d")

        # if pipeline.startswith('FX'):  #
        #     apm=time.strftime('%p')
        #     return today,apm
        if pipeline.startswith('Env'):
            today_week_num = self.getWeekNum(today)
            # print('today_week_num:', today_week_num)
            near_num = self.getNearWeekNum(today_week_num)
            # print('near_num:', near_num)
            delta = near_num - today_week_num
            last_date = self.dateAdd(today, delta)
            # print(last_date)
            return last_date,''
        else:
            apm=time.strftime('%p')
            return today,apm

if __name__ == '__main__':
    app = QApplication(sys.argv)
    # path=r'\\192.168.100.30\ZZ_project'
    # path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'Control')
    g = ExportMov()
    # g=ProjectList()
    data={'MZDYY':{'database': 'proj_mzdyy', 'entity_name': 'MZDYY', 'full_name': '��֭������'},'AAA':{'database': 'proj_mzdyy', 'entity_name': 'MZDYY', 'full_name': '��֭������'}}
    # g.set_data(data)
    # g=ShotListWindow()
    # g.set_data(data)
    g.show()
    sys.exit(app.exec_())
